﻿using System;
using Microsoft.AspNet.Identity;

using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security.Cookies;
using Microsoft.Owin.Security.DataProtection;
using Owin;
using CanDoo.Admin.Core.Identity;
using CanDoo.Admin.Core.Models;
using Microsoft.Owin.Security.OAuth;
using Microsoft.Owin.Security.Infrastructure;
using CanDoo.Oil.WebHost.Identity;
using CanDoo.Oil.WebHost.App_Start;

namespace CanDoo.Oil.WebHost
{
    public partial class Startup
    {

        public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
        public static string PublicClientId { get; private set; }

        // 有关配置身份验证的详细信息，请访问 http://go.microsoft.com/fwlink/?LinkId=301883
        public void ConfigureAuth(IAppBuilder app,IServiceProvider serviceProvider)
        {
            // 配置数据库上下文、用户管理器和登录管理器，以便为每个请求使用单个实例
            //app.CreatePerOwinContext(ApplicationDbContext.Create);
            //app.CreatePerOwinContext<UserManager>(UserManager.Create);
            //app.CreatePerOwinContext<ISignInManager>(ISignInManager.Create);

            // 使应用程序可以使用 Cookie 来存储已登录用户的信息
            // 使用 Cookie 临时存储有关某个用户使用第三方登录提供程序进行登录的信息
            // 配置登录 Cookie
            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                //AuthenticationMode= Microsoft.Owin.Security.AuthenticationMode.Passive,
                LoginPath = new PathString("/Login.aspx"),
                Provider = new CookieAuthenticationProvider
                {
                    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<UserManager, User, long>(
                        validateInterval: TimeSpan.FromMinutes(30),
                        regenerateIdentityCallback: (manager, user) => manager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie),
                        getUserIdCallback: ClaimsIdentity => long.Parse(ClaimsIdentity.GetUserId())
                        )
                }
            });
            // 使用 Cookie 临时存储有关某个用户使用第三方登录提供程序进行登录的信息
            app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

            // 使应用程序可以在双重身份验证过程中验证第二因素时暂时存储用户信息。
            app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));

            // 使应用程序可以记住第二登录验证因素，例如电话或电子邮件。
            // 选中此选项后，登录过程中执行的第二个验证步骤将保存到你登录时所在的设备上。
            // 此选项类似于在登录时提供的“记住我”选项。
            app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);


            // 针对基于 OAuth 的流配置应用程序
            PublicClientId = "self";
            OAuthOptions = new OAuthAuthorizationServerOptions
            {
                TokenEndpointPath = new PathString("/Token"),
                Provider = new ApplicationOAuthProvider(serviceProvider),
                // Refresh token provider which creates and receives referesh token
                //AuthorizeEndpointPath = new PathString("/api/pad/Login"),
                AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
                //在生产模式下设 
                //AllowInsecureHttp = false
                ApplicationCanDisplayErrors = true,
                //#if DEBUG
                AllowInsecureHttp = true,
                //#endif
                // Refresh token provider which creates and receives referesh token
                RefreshTokenProvider = new CandooRefreshTokenProvider()
            };

            // 使应用程序可以使用不记名令牌来验证用户身份
            app.UseOAuthBearerTokens(OAuthOptions);
            //app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

            // Token Generation
            //app.UseOAuthAuthorizationServer(OAuthOptions);
            // app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

            // 取消注释以下行可允许使用第三方登录提供程序登录
            //app.UseMicrosoftAccountAuthentication(
            //    clientId: "",
            //    clientSecret: "");

            //app.UseTwitterAuthentication(
            //   consumerKey: "",
            //   consumerSecret: "");

            //app.UseFacebookAuthentication(
            //   appId: "",
            //   appSecret: "");

            //app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
            //{
            //    ClientId = "",
            //    ClientSecret = ""
            //});
        }


        private void CreateRefreshToken(AuthenticationTokenCreateContext context)
        {
            string tokenValue = Guid.NewGuid().ToString("n");

            context.Ticket.Properties.IssuedUtc = DateTime.UtcNow;
            context.Ticket.Properties.ExpiresUtc = DateTime.UtcNow.AddYears(10);

            //_refreshTokens[tokenValue] = context.SerializeTicket();

            context.SetToken(tokenValue);
            context.SetToken(context.SerializeTicket());
        }

        private void ReceiveRefreshToken(AuthenticationTokenReceiveContext context)
        {
            context.DeserializeTicket(context.Token);
        }
    }
}
